//// Adds an administration section and a bug entry submission suggestion/confirmation.

///////// GLOBAL /////////

// When the document is ready, register our events.
$(document).ready(function() {
	registerEvents();
  
	addMiningToAdministration();
});

///////// ADMINISTRATION /////////

// Add a Mining link to the administration.
function addMiningToAdministration()
{
	$('dt#whining').next().after('<dt id="bug_severity_link"><a href="">Bug Prediction</a></dt><dd>Maintain the bug severity configuration here and view statistics on how well the bug severity classifier performs.</dd>');
	$('dt#bug_severity_link a').click(openBugPredictionPage);
}

// Open Bug Prediction page.
function openBugPredictionPage()
{
	$('div#bugzilla-body').html('<table border="0" width="100%"><tr><td width="170" valign="top"><table id="menu"><tbody></tbody></table></td><td id="content" valign="top"></td></tr></table>');
	$('table#menu').css('margin-right', '5px');
	
	// Add all the Bug Prediction admininstration links to the side menu.
	addLinkToMenu('Train Bug Prediction', 'Rebuild the bug prediction training files to add the most recent bugs. This will ensure up-to-date predictions.', pageTrainBugPrediction);
	addLinkToMenu('Change Classifier', 'Allows you to specify which classifier should be used by the system.', pageChangeClassifier);
	addLinkToMenu('Change Classification', 'You can change whether to classify using the title, the content or both.', pageChangeClassification);
	addLinkToMenu('Change Severity Map', 'You can specify which severities are handled and on which classes they are mapped.', pageChangeSeverityMap);
	addLinkToMenu('Statistics', 'View statistics for the latest 100 bug submits.', pageStatistics);
	return false;
}

// Add link to menu in Bug Prediction page.
function addLinkToMenu(name, description, action)
{
	var item = $('<tr><td><span title="' + description + '"><a href="">' + name + '</a></span></td></tr>');
	// Style the link, if we click it the according page function will be called.
	item.find('td').css('border', 'solid thin').css('padding', '0.2em 0.5em').find('a').click(function() {
		$('td#content').html('');
	
		action();
		
		return false;
	});
	
	$('table#menu tbody').append(item);
}

// Page: Train Bug Prediction
function pageTrainBugPrediction()
{
	// Fill in the page.
	var content = $('td#content');
	content.append('<h3>Train Bug Prediction for a single component</h3>');
	content.append('<p style="margin-top: 0px">Select a product and component for which to train the bug severity classifier:</p>');
	content.append('<select id="train_severity_product"></select><select id="train_severity_component"></select>');
	content.append('<input type="button" id="train_classifier" value="Train Classifier" />');
	content.find('select').css('margin-right', '5px');
	
	content.append('<h3>Train Bug Prediction for all components</h3>');
	content.append('<p style="margin-top: 0px">This button will update the Bug Prediction for all products and components.</p>');
	content.append('<input type="button" id="train-everything" value="Train Everything" />');
	
	// Get a list of products.
	$.getJSON('/extensions/BugPrediction/lib/admin/getProducts.cgi', function (products) {
		$.each(products, function (id, product) {
			$('select#train_severity_product').append('<option value="' + product[0] + '">' + product[1] + '</option>');
		});
	});
	
	// Make sure the components update when another product is selected.
	updateTrainBugPredictionComponents(1);
	
	$('select#train_severity_product').change(function () {
		$('select#train_severity_component').html('');

		updateTrainBugPredictionComponents($('select#train_severity_product').val());
	});
	
	// Event: Train the classifier for a single component.
	$('input#train_classifier').click(function() {
		var product_id = $('select#train_severity_product').val();
		var component_id = $('select#train_severity_component').val();
	
		$('td#content').html("<h3>Train Bug Prediction</h3><p>Training classifier, please wait...</p>");
		
		$.get('/extensions/BugPrediction/lib/trainClassifier.cgi', {pid: product_id , cid: component_id}, function (data) {
			$('td#content').html('<h3>Train Bug Prediction</h3><p>Done training component!</p>');
		});
	});
	
	// Event: Train the models using a classifier for all components.
	$('input#train-everything').click(function() {
		// Get the products.
		$.ajax({type: 'GET', dataType: 'json', url: '/extensions/BugPrediction/lib/admin/getProducts.cgi', async: false, success: function (products) {
			$('td#content').html('<h3>Train Bug Prediction</h3><p>Loading...</p>');
			
			// For each product, ...
			$.each(products, function (pid, product) {
				// ..., get the components.
				$.ajax({type: 'GET', dataType: 'json', url: '/extensions/BugPrediction/lib/admin/getComponents.cgi?id=' + product[0], async: false, success: function (components) {
					
					// For each component, ...
					$.each(components, function (cid, component) {
						// ..., train a model for the component.
						$('td#content').html('<h3>Train Bug Prediction</h3><p>Training Bug Prediction for product ' + product[1] + ' and component ' + component[1] + '...</p>');
						$.ajax({url: '/extensions/BugPrediction/lib/trainClassifier.cgi?pid=' + product[0] + '&cid=' + component[0], async: false});
					});
				}});
			});	
		}});
		
		$('td#content').html('<h3>Train Bug Prediction</h3><p>Done training all components!</p>');
	});
}

// Page: Train Bug Prediction
// Event: Update the components when another product is selected.
function updateTrainBugPredictionComponents(product)
{
	$.getJSON('/extensions/BugPrediction/lib/admin/getComponents.cgi', {id: product}, function (components) {
		$.each(components, function (id, component) {
			$('select#train_severity_component').append('<option value="' + component[0] + '">' + component[1] + '</option>');
		});
	});
}

// Page: Change Classifier
function pageChangeClassifier()
{
	$('td#content').html('<h3>Change Classifier</h3><p>Loading...</p>');
	
	// Get the classifier.
	$.get('/extensions/BugPrediction/lib/admin/getClassifier.cgi', function (classifier) {
		$('td#content').html('<h3>Change Classifier</h3><p>Choose an updatable WEKA classifier which the system should use and specify the non-input/output parameters.</p><form><input type="text" size="100" id="classifier" value="' + classifier + '" /><input type="button" id="classifier_update" value="Change" /></form>');
	
		// Event: Update the classifier.
		$('td#content').find('input#classifier_update').click(function () {
			$.post('/extensions/BugPrediction/lib/admin/setClassifier.cgi', {classifier: $('input#classifier').val()}, function () {
				$('td#content').html('<h3>Change Classifier</h3><p>The classifier has been changed, please update the bug prediction models!</p>');
			});
		});
	});
}

// Page: Change Classification
function pageChangeClassification()
{
	$('td#content').html('<h3>Change Classification</h3><p>Loading...</p>');

	// Get the classification.
	$.get('/extensions/BugPrediction/lib/admin/getClassification.cgi', function (classification) {
		$('td#content').html('<h3>Change Classification</h3><p>You can change whether to classify using the title, the content or both.</p><form><select id="classification"><option value="title">Title</option><option value="content">Content</option><option value="both">Both</option></select><input type="button" id="classification_update" value="Change" /></form>');
		$('select#classification').val(classification);
		
		// Event: Update the classification.
		$('td#content').find('input#classification_update').click(function () {
			$.post('/extensions/BugPrediction/lib/admin/setClassification.cgi', {classification: $('select#classification').val()}, function () {
				$('td#content').html('<h3>Change Classification</h3><p>The classification has been changed, please update the bug prediction models!</p>');
			});
		});
	});
}

// Page: Change Severity Map
function pageChangeSeverityMap()
{
	$('td#content').html('<h3>Change Severity Map</h3><p>Loading...</p>');
	
	// Get the severity map.
	$.get('/extensions/BugPrediction/lib/admin/getSeverityMap.cgi', function (severityMap) {
		$('td#content').html('<h3>Change Severity Map</h3><p>You can specify which severities are handled and on which classes they are mapped. Place each map on it\'s own line with the syntax "severity:class", the severity map is handled from top to bottom in case you specify duplicate severities or classes.</p><form><textarea id="severityMap" cols="80" rows="10"></textarea><input type="button" id="severityMap_update" value="Change" /></form>');
		$('textarea#severityMap').val(severityMap);
		
		// Event: Update the severity map.
		$('td#content').find('input#severityMap_update').click(function () {
			$.post('/extensions/BugPrediction/lib/admin/setSeverityMap.cgi', {severityMap: $('textarea#severityMap').val()}, function () {
				$('td#content').html('<h3>Change Severity Map</h3><p>The severity map has been changed, please update the bug prediction models!</p>');
			});
		});
	});
}

// Page: Statistics
function pageStatistics()
{
	$('td#content').html('<h3>Statistics</h3><p>Loading...</p>');

	// Get all the statistics and style the table.
	$.get('/extensions/BugPrediction/lib/admin/getStatistics.cgi', function (statistics) {
		$('td#content').html('<h3>Statistics</h3><p>View statistics for the latest 100 bug submits.</p>' + statistics);
		$('td#content td').css('border', 'solid 1px Black');
		$('td#content thead td').css('font-weight', 'bold');
	});
}


///////// NEW BUG ENTRY /////////

var submit = false;
var userSeverity, suggestedSeverity;

// Register events that are the result of user actions.
function registerEvents()
{  
  // Event: The user wants to send the form.
  $('input#commit').click(function () {
	// Verify that the form has been filled in correctly.
    if ($('input[name="short_desc"]').val() != '' && $('select[name="component"] :selected').val() != null)
    {
	  // Show a modal overlay where we will do our suggestion.
	  $('<div style="background-color: #F0F0F0; border: solid 2px Black; padding: 12px; width: 300px" id="severityAlert">Checking the severerity...</div>').modal();
	  $('#simplemodal-overlay').css('background-color', '#000');
	
	  // Determine the severity.
	  userSeverity = $('select#bug_severity').val();
	  determineSeverity();
	
	  return submit;
	}
	else
	{
	  if ($('select[name="component"] :selected').val() == null)
	  {
		window.alert('Please select a component.');
	  }
	
	  return false;
	}
  });
}

// AJAX: Determine the severity if the short description field has data, update the severity field.
function determineSeverity()
{
  // Verify that the form has been filled in correctly.
  if ($('input[name="short_desc"]').val() != '' && $('input[name="component"]').val() != '')
  {
    // Determine the severity.
	$.post('extensions/BugPrediction/lib/determineSeverity.cgi', {summary: $('input[name="short_desc"]').val(), content: $('textarea#comment').val(), product: $('input[name="product"]').val(), component: $('select[name="component"]').val(), severity: $('select#bug_severity').val(), train: 'false'}, function (data) {
      suggestedSeverity = data;
	  
	  // If the severities are the same: Train the component, store the statistics and submit the bug.
	  if (userSeverity == suggestedSeverity)
	  {
		$.post('extensions/BugPrediction/lib/determineSeverity.cgi', {summary: $('input[name="short_desc"]').val(), content: $('textarea#comment').val(), product: $('input[name="product"]').val(), component: $('select[name="component"]').val(), severity: $('select#bug_severity').val(), train: 'true'}, function () {
		  storeStatistics(userSeverity, userSeverity, userSeverity);
		  
		  $.modal.close();
		  submit = true;
		  $('input#commit').click();
		});
	  }
	  else
	  {
	    // If they are not the same, let the user agree, declines or cancel the suggestion.
		$('div#severityAlert').html('<p>A suggestion for the severity of your bug has been made to help you, please check if the suggested severity is correct.</p><p style="float: left" class="alertSeverityLeft"><b>Your severity:</b><br />' + userSeverity + '</p><p style="float:right" class="alertSeverityRight"><b>Suggested severity:</b><br />' + suggestedSeverity + '</p><div style="display:block; margin: 0px auto; width: 100%; clear: both; text-align: center"><div><input id="alertAgree" type="button" value="Agree"/>&nbsp;<input id="alertDecline" type="button" value="Decline"/>&nbsp;<input id="alertCancel" type="button" value="Cancel"/></div>');
        $('p.alertSeverityLeft').css('margin', '0px 20px 10px 0px');
		$('p.alertSeverityRight').css('margin', '0px 0px 10px 20px');
		
		// If he agrees, the suggested severity will be chosen: Train the component, store the statistics and submit the bug.
		$('input#alertAgree').click(function () {
		  $.post('extensions/BugPrediction/lib/determineSeverity.cgi', {summary: $('input[name="short_desc"]').val(), content: $('textarea#comment').val(), product: $('input[name="product"]').val(), component: $('select[name="component"]').val(), severity: $('select#bug_severity').val(), train: 'true'}, function () {
		    $('select#bug_severity').val(suggestedSeverity);
			storeStatistics(userSeverity, suggestedSeverity, suggestedSeverity);
			$.modal.close();
		    submit = true;
		    $('input#commit').click();
		  });
		});
		
		// If he declines, the user severity will be chosen: Train the component, store the statistics and submit the bug.
		$('input#alertDecline').click(function () {
		  $.post('extensions/BugPrediction/lib/determineSeverity.cgi', {summary: $('input[name="short_desc"]').val(), content: $('textarea#comment').val(), product: $('input[name="product"]').val(), component: $('select[name="component"]').val(), severity: $('select#bug_severity').val(), train: 'true'}, function () {
		    $('select#bug_severity').val(userSeverity);
			storeStatistics(userSeverity, suggestedSeverity, userSeverity);
			$.modal.close();
		    submit = true;
		    $('input#commit').click();
		  });
		});
		
		// If he cancels, just close the modal so that the user can correct the fields of the form if he wants to.
		$('input#alertCancel').click(function () {
		  $.modal.close();
		});
      }
	});
  }
}

// Store bug suggestion statistics in the database.
function storeStatistics(user, suggested, choice)
{
    $.ajax({type: 'GET', url: '/extensions/BugPrediction/lib/admin/addStatistic.cgi?user=' + user + '&suggested=' + suggested + '&choice=' + choice, async: false});
}